﻿using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;

namespace Stock.Client.Queue
{
      public abstract class QueueHelper<T>
      {
            private ConcurrentQueue<T> models = new ConcurrentQueue<T>();
            private ManualResetEvent _event = new ManualResetEvent(false);
            private bool state = true;

            public QueueHelper()
            {
                  new Thread(() =>
                  {
                        while (true)
                        {
                              _event.WaitOne();
                              while (models.Any())
                              {
                                    T model;
                                    if (models.TryDequeue(out model))
                                    {
                                          try
                                          {
                                                Execute(model);
                                          }
                                          catch(Exception ex)
                                          {
                                                models.Enqueue(model);
                                          }
                                    }

                              }
                              state = true;
                              _event.Reset();
                        }
                  })
                  { IsBackground = true }.Start();
            }

            /// <summary>
            /// 执行方法
            /// </summary>
            /// <param name="model"></param>
            public abstract void Execute(T model);

            /// <summary>
            /// 添加元素并恢复线程
            /// </summary>
            /// <param name="model"></param>
            public void Add(T model)
            {
                  models.Enqueue(model);
                  if (state)
                  {
                        state = false;
                        _event.Set();
                  }
            }



      }
}
